home *** CD-ROM | disk | FTP | other *** search
- Path: kbad.eglin.af.mil!rpi!not-for-mail
- From: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
- Newsgroups: comp.lang.c++.moderated,comp.lang.c++
- Subject: Re: I don't believe it! Weird thing about Virtual tables
- Followup-To: comp.lang.c++.moderated,comp.lang.c++
- Date: 16 Apr 1996 15:35:28 -0000
- Organization: FakultΣt fⁿr Mathematik und Informatik
- Sender: cppmods@netlab.cs.rpi.edu
- Approved: kanze@lts.sel.alcatel.de
- Message-ID: <4l0eo0$r44@netlab.cs.rpi.edu>
- References: <4ku0ee$hjj@netlab.cs.rpi.edu>
- Reply-To: dietmar.kuehl@uni-konstanz.de
- NNTP-Posting-Host: netlab.cs.rpi.edu
- X-Original-Date: 16 Apr 1996 09:16:55 GMT
-
- Hi,
- Rodrigo de Salvo Braz (braz@ime.usp.br) wrote:
- : Debugging a project in Borland C++ 4.0, I noticed something
- : unexpected...
-
- : The virtual table of one of my classes (say, Dog) is initialized by
- : code!
-
- This is a reasonable thing to do: Remember that the virtual functions
- used may change in the process of constructing an object of a derived
- class. Consider e.g. this simple example:
-
- #include <iostream.h>
-
- class A
- {
- public:
- virtual char const *f() { return "A::f()"; }
- A() { cout << "A::A(): " << f() << endl; }
- ~A() { cout << "A::~A(): " << f() << endl; }
- };
-
- class B: public A
- {
- public:
- virtual char const *f() { return "B::f()"; }
- B() { cout << "B::B(): " << f() << endl; }
- ~B() { cout << "B::~B(): " << f() << endl; }
- };
-
- int main() { B b; return 0; }
-
- The output of this simple program is
-
- A::A(): A::f()
- B::B(): B::f()
- B::~B(): B::f()
- A::~A(): A::f()
-
- This just demonstrates the rule that the call to a virtual function
- from a constructor or a destructor uses a static function lookup. To
- implement this easily, it is reasonable to initialize the virtual
- function table with the relevant table of the base class before the
- base class constructor is called. Then this virtual function table is
- replaced by the virtual function table for the derived class before the
- derived class constructor is called. Likewise for the destructor.
-
- : It sounds ok at first, but since each module has its own initializing
- : code (for global variables and similar stuff), I have Dog's virtual
- : table initialized AFTER initializing code of modules located BEFORE
- : Dog's module in the Project definition. Since I have variables using
- : Dog in those earlier modules, I get a real crash!
-
- The real problem is not that the virtual function table is not
- initialized but that your object is used before it is constructed:
- Since C++ provides no mechanism to define the order of construction
- (and destruction) of global objects, you should avoid using them, at
- least if some of your objects depend on others to be constructed when
- they are constructed themselves (or, in the reverse, that the objects
- are not yet destructed when they are destructed themselves). You can
- avoid this problem (for the construction of the objects) by wrapping
- the necessary global objects into functions like this:
-
- T &global_T() { static T object(/*...*/); return object; }
-
- : So I have to worry about the modules definition order in the project
- : in order to have my program working properly, and that sounds really
- : odd!
-
- Yes, this is odd because you rely on a very system dependent mechanism
- instead of removing the problem.
-
- : Am doing any mistake on it? Is there any option preventing it? Why
- : doesn't the compiler create the virtual tables already initialized?
-
- See above. Although the compiler can use a different mechanism to
- ensure that the virtual functions depend on the static type in the
- constructor and the destructor, there is no requirement to do so: Using
- a non-static member function on an object before construction begins,
- results in undefined behavior anyway (12.7 [class.cdtor] of the DWP).
- This is what you are attempting and what you get: undefined behavior.
- - --
- dietmar.kuehl@uni-konstanz.de
- http://www.informatik.uni-konstanz.de/~kuehl/
- I am a realistic optimist - that's why I appear to be slightly pessimistic
-
- [ Articles to moderate: mailto:c++-submit@netlab.cs.rpi.edu ]
- [ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
- [ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
- [ Comments? mailto:c++-request@netlab.cs.rpi.edu ]
-